# !/usr/bin/env python3
# coding=utf8
"""
sqlite 里的数据表 dbbardata 的检查者(检查 dbbardata 里的数据有没有缺失)
"""
import datetime
import pandas
import pandas.core.groupby.generic
import pathlib
import sqlite3
from typing import Dict, List, Set, Tuple, Optional, Union, Callable

from vnpy.trader.constant import Exchange, Interval
from vnpy.trader.utility import get_file_path

from vnpy_zxtools.chinese_mainland_time_config import ChineseMainlandTimeConfig


class DbBarDataChecker(object):
    """
    DbBarData检查者
    """

    DBPATH: pathlib.Path = get_file_path("database.db")

    @classmethod
    def load_dababase(cls) -> pandas.DataFrame:
        """"""
        sql_statement: str = """
            SELECT exchange, symbol, interval, DATE(datetime) AS ndate, COUNT(*) AS count FROM dbbardata 
                WHERE interval = '1m' 
                GROUP BY exchange, symbol, interval, ndate;
            """

        with sqlite3.connect(database=cls.DBPATH) as connection:
            df: pandas.DataFrame = pandas.read_sql(
                sql=sql_statement,
                con=connection,
            )

            df["ndate"] = pandas.to_datetime(df["ndate"])  # 将 str 转成 pandas.Timestamp 类型,

            return df

    @classmethod
    def calc_for_load(cls, df: pandas.DataFrame):
        """"""
        return df

    @classmethod
    def gen_data(cls, df: pandas.DataFrame) -> pandas.DataFrame:
        """"""
        # temp = df.groupby(["exchange", "symbol", "interval"])
        # assert isinstance(temp, pandas.core.groupby.generic.DataFrameGroupBy)
        # print(temp.groups)

        lines: List[dict] = []

        data1: pandas.DataFrame = df.groupby(["exchange", "symbol", "interval"])["ndate"].aggregate(["min", "max"])

        for row in data1.itertuples():
            assert isinstance(row.Index, tuple)

            exchange, symbol, interval = row.Index
            min_ndate: datetime.datetime = row.min.to_pydatetime()
            max_ndate: datetime.datetime = row.max.to_pydatetime()

            assert interval == Interval.MINUTE.value

            dttms: List[datetime.datetime] = ChineseMainlandTimeConfig.calc_for_days(
                exchange=Exchange(exchange),
                symbol=symbol,
                window=1,
                is_left=True,
                add_boundary_dttm=False,
                is_default=False,
                business_days=None,
                start_date=min_ndate,
                end_date=max_ndate,
            )

            items = [
                {"exchange": exchange, "symbol": symbol, "interval": interval, "datetime": dttm, "ndate": dttm.date()} for dttm in dttms
            ]

            lines.extend(items)

        data2: pandas.DataFrame = pandas.DataFrame(data=lines)

        data2["ndate"] = pandas.to_datetime(data2["ndate"])  # 将 datetime.date 转成 pandas.Timestamp 类型,

        return data2

    @classmethod
    def calc_for_gen(cls, df: pandas.DataFrame):
        """"""
        data1 = df.groupby(["exchange", "symbol", "interval", "ndate"])["ndate"].aggregate(["count"])

        data1.reset_index(inplace=True)

        return data1

    @classmethod
    def check(cls) -> None:
        """"""
        df1: pandas.DataFrame = cls.load_dababase()
        df2: pandas.DataFrame = cls.gen_data(df=df1)

        df3: pandas.DataFrame = cls.calc_for_load(df=df1)
        df4: pandas.DataFrame = cls.calc_for_gen(df=df2)

        df: pandas.DataFrame = pandas.merge(left=df3, right=df4, on=["exchange", "symbol", "interval", "ndate"], how="outer")  # noqa E501

        df.sort_values(by=["exchange", "symbol", "interval", "ndate"], ascending=True, axis=0, inplace=True)

        return df


if __name__ == "__main__":
    df0: pandas.DataFrame = DbBarDataChecker.check()

    df1: pandas.DataFrame = df0[df0["count_x"] != df0["count_y"]]

    pandas.set_option('display.max_rows', None)  # 显示所有行

    print(df1)
